perm filename 11FTP.SAI[11,HE]12 blob sn#635199 filedate 1982-01-04 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	BEGIN "11FTP"
C00004 00003	! Auxiliary routines: parse10, parse11, outbuf, inbuf
C00008 00004	! Main program - initialization
C00013 00005	! Command loop - Exit & Alias
C00016 00006	! Store 11file ← 10file
C00021 00007	! Get 10file ← 11file & Fin
C00026 ENDMK
C⊗;
BEGIN "11FTP"

DEFINE	CRLF="('15&'12)",
	CR  ="'15",
	LF  ="'12",
	FF  ="'14",
	! = "COMMENT ",
	TIL="STEP 1 UNTIL";

REQUIRE "11UTIL.HDR[11,SYS]" SOURCE_FILE;

DEFINE TTYSET = "'047000400121";
DEFINE GETLIN = "'051300000000";
DEFINE GETPPN = "'047000000024";
DEFINE DSKPPN = "'047000400071";

INTEGER pn,proj;	! Who's running ftp?;
INTEGER aliaspn, aliasproj;	! Alias of runner;
INTEGER chan;		! Channel number for I/O to RSX;
INTEGER dskchan;  	! Channel number for 10 disk I/O;
EXTERNAL INTEGER _SKIP_;

INTEGER ARRAY buffer[1:256];
INTEGER talk10,char,p,i,j,k,l,dum,command,brk,brk1;
INTEGER eof,base,bufadr,bufptr,warn,gotline,needprompt;
STRING f1,f2,s,q,com,ack,fdev11,fnam10,fnam11,fext10,fext11,fver11,ppn10,ppn11;
STRING alppn11,aldev11;
LABEL fin;

! Auxiliary routines: parse10, parse11, outbuf, inbuf;

PROCEDURE parse10 (STRING s);
  BEGIN
  fnam10 ← fext10 ← ppn10 ← NULL;
! WHILE s=" " ∧ s ≠ NULL DO dum ← LOP(s);	! Strip off leading blanks;
  WHILE s≠"." ∧ s≠"[" ∧ s≠NULL DO fnam10 ← fnam10 & LOP(s);  ! Build up file name;
  WHILE s≠"[" ∧ s≠NULL DO fext10 ← fext10 & LOP(s);	! Build up file extension;
  IF s="[" THEN ppn10 ← s;		! Set ppn if present;
  END;

PROCEDURE parse11 (STRING s);
  BEGIN
  fdev11 ← aldev11;
  ppn11 ← alppn11;
  fnam11 ← fext11 ← NULL;
  fver11 ← ";0";	! Default version number - means most recent version;
! WHILE s=" " ∧ s ≠ NULL DO dum ← LOP(s);	! Strip off leading blanks;
  IF s≠"[" ∧ (s[2 FOR 1]=":" ∨ s[3 FOR 1]=":" ∨ s[4 FOR 1]=":") THEN
    BEGIN				! Set device name;
    fdev11 ← LOP(s);
    WHILE s≠":" DO fdev11 ← fdev11 & LOP(s);
    fdev11 ← fdev11 & LOP(s);
    END;
  IF s="[" THEN				! Set ppn if present;
    BEGIN
    ppn11 ← NULL;
    DO ppn11 ← ppn11 & LOP(s) UNTIL s="]" ∨ s=NULL;	! Build up ppn;
    ppn11 ← ppn11 & LOP(s);				! Tack on final "]";
    END;
  WHILE s≠"." ∧ s≠";" ∧ s≠NULL DO fnam11 ← fnam11 & LOP(s);  ! Build up file name;
  WHILE s≠";" ∧ s≠NULL DO fext11 ← fext11 & LOP(s);	! Build up file extension;
  IF s=";" THEN fver11 ← s;		! Set version number if present;
  END;

PROCEDURE OUTBUF;
  BEGIN
  WHILE (bufadr←PEEK(bufptr))=0 DO CALL(0,"SLEEP");   ! Sleep for 1 tick;
  IF bufadr LAND 1 THEN   ! Something's wrong - abort;
    BEGIN
    IF talk10 THEN PRINT("Error while writing file"&crlf);
    GO TO fin;
    END;
  bufadr ← bufadr + base;
  IF j THEN POKE(bufptr+2,j);		! Tell 11 this is last block;
  POKEARRAY(bufadr,256,buffer,0);	! Transfer the sector over;
! POKEARRAY(bufadr,256,buffer,TWRJ);	! Transfer the sector over;
  POKE(bufptr,0);			! Tell 11 to empty buffer now;
  i ← 1;
  END;

PROCEDURE INBUF;
  BEGIN
  WHILE (bufadr←PEEK(bufptr))=0 DO CALL(0,"SLEEP");   ! Sleep for 1 tick;
  IF bufadr LAND 1 THEN	! Something's wrong - abort;
     BEGIN
     IF talk10 THEN PRINT("Error while reading file"&crlf);
     GO TO fin;
     END;
  bufadr ← bufadr + base;
  PEEKARRAY(bufadr,256,buffer,0);	! Transfer the sector over to 10;
  j ← PEEK(bufptr+2) DIV 2;		! Get first free word if last block;
  POKE(bufptr,0);			! Tell 11 we're done with buffer;
  i ← 1;
  END;

! Main program - initialization;

SETBREAK(1,crlf,NULL,"INS");
SETBREAK(2,lf&ff,cr,"INS");
SETBREAK(3,"←~}↓αβ∧¬ελ∞∂⊂⊃∩∪∀∃⊗↔_→≠≤≥≡∨",NULL,"INS");	! Conversions for 11;
SETBREAK(4,"~"&'137&'175,NULL,"INS");			! Conversions from 11;
SETBREAK(5,"=←"," ","KINS");				! Convert to uppercase;

aldev11 ← "AL:";	! Standard aliasing;
QUICK_CODE
 GETPPN '13,;		! Who's running us?;
 HRLZM '13,PN;     	! Find out Prog.name;
 HLLZM '13,PROJ;	! Find out what project;
 SETZ  '13,;		! Now find out what they're aliased to;
 DSKPPN '13,;		! Put aliased PPN in 13 (code=0 to find out alias);
 HRLZM '13,ALIASPN;	! Get prog.name of alias;
 HLLZM '13,ALIASPROJ;	! and prj;
 END;
alppn11 ← IF pn = CVSIX("ARG") THEN "[1,10]"
	ELSE IF pn = CVSIX(" RV") THEN 
	    IF aliasproj=CVSIX("PRJ") THEN "[7,16]" ELSE "[5,10]"
	ELSE IF pn = CVSIX("JJC") THEN "[5,5]"
	ELSE IF pn = CVSIX(" OK") THEN "[5,6]"
	ELSE IF pn = CVSIX("SHM") THEN "[3,12]"
	ELSE "[200,200]";
IF pn=CVSIX(" RV") ∧ aliasproj=CVSIX("PRJ") THEN aldev11 ← "DK1:";

ALINIT(false);	! Assign the ELF, but don't care about ARM;

! See whether 10 or 11 is requesting the transfer;

talk10 ← -1;
CODE(GETLIN,talk10);	! talk10 now has terminal characteristics & line number;
talk10 ← IF (talk10 LAND '7777)='53 THEN FALSE ELSE TRUE;

IF talk10 THEN
  BEGIN
  PRINT(crlf & "10-11 FTP Program.  Type ? for help.",crlf);
  PRINT ("Default 11 PPN for you is ",aldev11,alppn11,crlf,crlf);
  chan ← GETCHAN;
  OPEN(chan,"TTY53",0,1,1,999,brk1,dum);
    QUICK_CODE
	LABEL XIT,SETUP;
	HRRI '13,SETUP;		    ! Command list to initialize the tty;
	HRLI '13,-3;		    ! Number of commands;
	TTYSET '13,0;		    ! Do it;
	JRST	XIT;
SETUP:
!	'072453000001;		! Set TTY EXIST;
!	'040453000005;		! Set tty speed = 1200 baud;
	'001453000004;		! Set (XON &) NO ECHO;
	'002453010000;		! Set TTY NO ARROW?;
	'023453000001;		! Set TTY GAG;
XIT:	END;

! OUT(chan,"RUN $11FTP"&crlf);
  OUT(chan,"RUN $11FTP/CKP=NO"&crlf);	! If checkpointed the buffer would shift;
  WHILE INPUT(chan,1) = NULL DO ;	! Ignore echo from RSX;
  WHILE (s←INPUT(chan,1)) = NULL ∨ s=">" DO ;
  base ← CVO(s) LSH 6;			! Get address of Partition Base;
! PRINT("Partition base = ",CVOS(base),crlf);
  WHILE (s←INPUT(chan,1)) = NULL DO ;
  bufptr ← CVO(s);			! Get address of buffer pointer;
! PRINT("Buffer pointer = ",CVOS(bufptr),crlf);
  END
 ELSE
  BEGIN
  base ← CVO(INCHWL) LSH 6;		! Get address of buffer pointer;
  bufptr ← CVO(INCHWL);			! Get address of buffer pointer;
  END;
bufptr ← base + bufptr;

dskchan ← GETCHAN;
OPEN(dskchan,"DSK",0,19,19,512,brk,eof);

! Command loop - Exit & Alias;

needprompt ← TRUE;	! Prompt needed flag;
WHILE TRUE DO		! Get a command & do what needs doing;
  BEGIN
  IF needprompt THEN PRINT("*");
  warn ← 0;
  com ← INCHSL(gotline);	! Read command;
  IF gotline≠0 THEN 		! If no line input yet;
    BEGIN
    CALL (1,"SLEEP");		! Go to sleep for one sec;
    needprompt ← FALSE;		! Don't prompt next time;
    CONTINUE;
    END;

  needprompt ← TRUE;		! Prompt them next time around;
  command ← LOP(com) LOR '40;	! command = x, q, e, d, g or s for now;
  IF command = "x" ∨ command = "e" ∨ command = "q" ∨ command = "d" THEN
    BEGIN
    IF talk10 THEN OUT(chan,"E"&cr&cr);	! Tell 11 that we're done;
!   IF talk10 THEN OUT(chan,"X"&cr&cr);	! Tell 11 that we're done;
    WHILE (s←INPUT(chan,1)) = NULL ∨ s≠">" DO ;	! Wait for MCR prompt;
    i ← WORDIN(chan);		! This should clear the buffer;
    IF command = "d" THEN
      BEGIN			! Now invoke DIAL;
      CLRBUF;
      PTOSTR(0,"DIAL TTY53"&crlf);
      END;
    CALL(0,"EXIT");
    END;

  f1 ← SCAN(com,5,i);	! Get first file name & convert it to upper case;
  f2 ← SCAN(com,5,i);	! Get second file name & convert it to upper case;
  IF command = "a" THEN
    BEGIN		! Get device & UIC alias for 11;
    parse11(f1);	! Info now in fdev11 & ppn11;
    aldev11 ← fdev11;
    alppn11 ← ppn11;
    END
! Store 11file ← 10file;

  ELSE IF command = "s" THEN
    BEGIN		! Store 11file ← 10file;
    IF talk10 THEN
      BEGIN
      PARSE11(f1);
      PARSE10(f2);
      IF fnam11 = NULL THEN fnam11 ← fnam10;
      IF fext11 = NULL THEN fext11 ← fext10;
      IF fnam10 = NULL THEN fnam10 ← fnam11;
      IF fext10 = NULL THEN fext10 ← fext11;
      END
     ELSE PARSE10(f1);
    LOOKUP(dskchan,fnam10 & fext10 & ppn10,i);
    IF i THEN
      BEGIN PRINT("ABORTED - Can't find:",fnam10,fext10,ppn10,crlf); GO TO fin END;
    IF talk10 THEN
	BEGIN		! Tell 11 name of file to create;
	OUT(chan,"G " & fdev11 & ppn11 & fnam11 & fext11 & fver11 & cr);
	WHILE INPUT(chan,1) = NULL DO ; ! Ignore echo;
	WHILE (s←INPUT(chan,1)) = NULL DO ;
	IF ¬EQU("OK",s) THEN
	  BEGIN PRINT("Aborted by 11 "&s&crlf); GO TO fin END;
	END
     ELSE PRINT("OK"&crlf);
    eof ← FALSE;
    i ← j ← 0;
    s ← INPUT(dskchan,2);		! Read in the first line;
    IF EQU(s[1 FOR 9],"COMMENT ⊗") THEN
	BEGIN   ! Skip over E directory page;
	DO s ← INPUT(dskchan,2)		! Read in the next line;
	    UNTIL EQU(s[1 FOR 3],"C⊗;") ∨ eof;
	IF eof THEN
	    BEGIN
	    IF talk10 THEN PRINT("Directory end not detected"&crlf);
	    s ← NULL;
	    END;
	s ← INPUT(dskchan,2);	! Skip ff;
	s ← INPUT(dskchan,2);	! Read in the first real line;
	END;
    DO BEGIN			! Start transferring characters to the 11;
	q ← NULL;
	WHILE s≠NULL DO
	    BEGIN		! Convert Stanford ASCII to standard ASCII;
	    q ← q & SCAN(s,3,char);	! Scan to next conversion;
	    IF char = 0 THEN		! nothing to do;
	    ELSE IF char = "~" THEN q ← q & '176
	    ELSE IF char = "}" THEN q ← q & '175
	    ELSE IF char = "_" THEN q ← q & '137
	    ELSE IF char = "←" THEN q ← q & ":="	! Be nice here;
	    ELSE IF char = "≥" THEN q ← q & ">="
	    ELSE IF char = "≤" THEN q ← q & "<="
	    ELSE IF char = "≠" THEN q ← q & "<>"
	    ELSE IF char = "¬" THEN q ← q & " not "
	    ELSE IF char = "∧" THEN q ← q & " and "
	    ELSE IF char = "∨" THEN q ← q & " or "
	    ELSE BEGIN
		IF warn=0 THEN PRINT("Nonstandard chars: ");
		OUTCHR (char); PRINT(" ");
		warn ← warn + 1;	! Count characters we omitted;
		END;
	    END;
	s ← q;
	IF brk = ff THEN s ← s & ff;
	IF (i←i+1) > 256 THEN OUTBUF;
	buffer[i] ← LENGTH(s);	! How long is this record?;
	WHILE s ≠ NULL DO	! Stick them in the buffer 2/wd;
	  BEGIN
	  IF (i←i+1) > 256 THEN OUTBUF;
	  buffer[i] ← LOP(s) + (LOP(s) LSH 8);
!	  buffer[i] ← (LOP(s) LSH 18) + (LOP(s) LSH 26) + LOP(s) + (LOP(s) LSH 8);
	  END;
	s ← INPUT(dskchan,2);	! Read in the next line;
       END UNTIL eof ∧ LENGTH(s)=0;
    j ← 2*i;				! First free byte address;
    FOR k ← i+1 TIL 256 DO buffer[k]←0;	! Clear out end of block;
    OUTBUF;				! And send it over to the 11;
    END
α! Get 10file ← 11file & Fin;

   ELSE IF command = "g" THEN
    BEGIN		! Get 10file ← 11file;
    PARSE10(f1);
    PARSE11(f2);
    IF fnam10 = NULL THEN fnam10 ← fnam11;
    IF fext10 = NULL THEN fext10 ← fext11;
    IF fnam11 = NULL THEN fnam11 ← fnam10;
    IF fext11 = NULL THEN fext11 ← fext10;
    LOOKUP(dskchan,fnam10 & fext10 & ppn10,i);	! Does file already exist?;
    IF ¬i THEN 					! File exists: ask for confirmation;
      	BEGIN
	i ← i LAND '777777;			! Look at right half = error bits;
	IF i≠0 THEN BEGIN
          PRINT("ABORTED - Can't enter:",fnam10,fext10,ppn10,crlf); GO TO fin END;
	IF i=0 THEN PRINT("File already exists: ",fnam10&fext10&ppn10,"  Replace? ");
	DO
	  BEGIN
	  i := inchrw;				! Wait for them to type a char;
	  PRINT(CRLF);
	  IF i="N" ∨ i="n" THEN BEGIN PRINT("Aborted.",CRLF); GO TO FIN END;
	  IF i≠"Y" ∧ i≠"y" THEN PRINT("  Replace (y/n)? ");
	  END
	UNTIL i="y" ∨ i="Y";
	END;
    CLOSE(dskchan);				! Close file we opened for input;

    ENTER(dskchan,fnam10 & fext10 & ppn10,i);	! Now open file for output;
    IF i THEN
      BEGIN PRINT("ABORTED - Can't enter:",fnam10,fext10,ppn10,crlf); GO TO fin END;
    IF talk10 THEN
	BEGIN		! Tell 11 name of file to read;
	OUT(chan,"S " & fdev11 & ppn11 & fjam11 & Fext11 & fver11 & cr);
	WHILE INPUT(chan,1) = NULL DG ; ! Ignore echo;
	WHIHE (s←INPUT(chan,1)) = NULL DM ;
	IF ¬EQU("OK",s) THEN	
	  BEGIL PBILT("Aborted by 11 "&q&crlf)3 GO TO fin END;
	END
     ELSE PRINT("OK"&crlf);
    i ← 256;
    j ← 0;
    WHILE j=0 ∨ i<j DO		! Start transfEpring characterpεAi↑↓iQJ@D`v~∀%¬β∂∪8~∀@@@@@@↓∪@Q%?RVb$@t@DTlA)⊃∃_A∪≥	+v~(@@@@@@AV↓>AEk→MKe7%:v∩∩∧AπKh↓EsiJ↓G←k]Pv~∀∪LA>A≥U→_v~(∪
∨$↓XA>@DA')@@dA,rR&1∧¬2∧$q∀∩π.n⊗≡Z∞Mε.jhM⎇(≥~T_Y1Ll<HE}y∞c!!(λ⊂HXp3C!!(λ∩(dλ~7m∃l*(πdM-D
⊂⊃3D	3PU(gc"B$∧≤λ↔d
⊃r3JE∞_N\YY4K≥4εV→
TYDPH_XP#≠y⊂∩/wd;
	  char ← LDB(p);
	  s ← s & IH		∧αCA%↓2β∂#π⊂π0hR⊃∀απ
t∧L@⊃⊂B∞¬(	H=_8@≥CE⊂DPλ1t0yλ/P$f⊃!∀8∀NFE⊂DH⊂9P/H9P∪⊂≤P∪⊂$S"!∀8
P∪⊂!Z0y≥FB∧P⊂"S ∧;
	IF K MOD2 THEL∧AfA|Ag6B↓
∨$AαZul4PKEα⎇∧rV"⊃Xh &↑DJ2*∞34`*3∪λλIc"B$∧λλ⊂HXp3B!∀(⊂p↔[;2y:λ9z0w→0y2 ASCII to Sta`≥Mα{@⊗"λ~4≤L↔1P@J∧∧απ
	tπ
αd
4e∞2c"L=ε∂∩↔1∩
¬<8λ-d≥≠h
l>≥={]Y.9tww∞FE∧Pλ⊂⊂$cλ1t0yλ⊂=   THEN		! nothing to @⊃↑v~∀$@@@A∃→'
A%AGQ¬d@z@≤bnlAQ⊃β≤ADA>AbL@D4λ~∀α@@A→M
Aβ↓GQCdz@Nb\jA)⊃∃≤AbA|Ab@LE|D~(∩@@@↓⊃'
↓∪AG!Cd@zNbfn↓)⊃≤↓bA>AD@L@D`D∩∀∩@@A1'
Ao¬e\A>↓oCe\V@bv$BAπ←U]hAG!CeCGQKefA]JA←[%iaKHl~∀α@@A≥⊂v~∀∪LA>Abl~∀β∪_A#*!fYML$A)⊃8A∨+(!IgWG!C\Yf$~∀α∩@@@A∃→'
A=+(AIMWGQC8Yf@L↓GeIL$r@@B↓(∂Kπ&)β?W"βS#∃εs↔cQεc';∃Xh(&⊗t!l4)α↓↓α⊗t 4)↓αα⊗"N*α&→β≤{77πv!u	]⊂αR"⊗rα
⊗≡Lq↓
#.cAβSF+5β?/!λ4)α↓↓↓α¬∩&:QB∩≥βSzβ∨↔Qε	β≠'f)β≠K}iβS#*↓EE	6≠K3→KX4)↓α↓↓αB∀J:Q!∃→βS=π≠S?K*β¬β≠Lc∃β?rβS#∃β	E	≠≥∪3→%Xh)↓↓α↓αBJLrQ!

βS-β≡+Qβπrβπ3'∂→β∪↔6K∂∃↓2αV&
ε{9βSF)↓EEπ[∪↔≠∂+3Qu∧
1i	d3CCs	E1r⊃≠∂Kf1%l4R↓↓↓↓¬αJ&:"A
aβ&yβ↔cO!	↓≠∨∪3→%Xh)↓↓α↓αBJLrQ!
"β≠?I∧"&ε1∩↓≠∂Kf1≠∂Kf1%l4R↓↓↓↓∧*:⊂4R↓↓α⊗e~∃αB∀J:Q!∃+;/;␈;9β∂}k7π;"⊃3∂Kf1%l4V3'9hhQ↓α∞dzN∃#'≠/∂#∞q%l4R↓α&→π;πK9¬""⊗9h)↓↓ααBJ&u!!	*<
J:&t9)↓5ε3'3∃ε≠?;S∞K;↔⊃R↓	3←∂∪91	εs?;O&;∪π⊗!β∂#∂∪π∂S/∪M9	6≠K3→KX4)↓∧*:⊃lhP4*⊗t!↓	E2RA	Xh(